/*
 * @Description: 该固件为控制LX-824串口舵机调试板使用
 * @Version: V1.0.0
 * @Author: Troubadour
 * @Date: 2022-08-31 21:59:42
 * @LastEditors: Troubadour
 * @LastEditTime: 2022-09-25 18:52:34
 */

#ifndef  __ROBOTSERVOFW_H__
#define  __ROBOTSERVOFW_H__

#include <Arduino.h>
#if !(defined(ESP8266) || defined(ESP32))
#include <SoftwareSerial.h>
#endif

#define ROBOT_SERVO_FRAME_HEADER         0x55
#define ROBOT_SERVO_MOVE_TIME_WRITE      1
#define ROBOT_SERVO_MOVE_TIME_READ       2
#define ROBOT_SERVO_MOVE_TIME_WAIT_WRITE 7
#define ROBOT_SERVO_MOVE_TIME_WAIT_READ  8
#define ROBOT_SERVO_MOVE_START           11
#define ROBOT_SERVO_MOVE_STOP            12
#define ROBOT_SERVO_ID_WRITE             13
#define ROBOT_SERVO_ID_READ              14
#define ROBOT_SERVO_ANGLE_OFFSET_ADJUST  17
#define ROBOT_SERVO_ANGLE_OFFSET_WRITE   18
#define ROBOT_SERVO_ANGLE_OFFSET_READ    19
#define ROBOT_SERVO_ANGLE_LIMIT_WRITE    20
#define ROBOT_SERVO_ANGLE_LIMIT_READ     21
#define ROBOT_SERVO_VIN_LIMIT_WRITE      22
#define ROBOT_SERVO_VIN_LIMIT_READ       23
#define ROBOT_SERVO_TEMP_MAX_LIMIT_WRITE 24
#define ROBOT_SERVO_TEMP_MAX_LIMIT_READ  25
#define ROBOT_SERVO_TEMP_READ            26
#define ROBOT_SERVO_VIN_READ             27
#define ROBOT_SERVO_POS_READ             28
#define ROBOT_SERVO_OR_MOTOR_MODE_WRITE  29
#define ROBOT_SERVO_OR_MOTOR_MODE_READ   30
#define ROBOT_SERVO_LOAD_OR_UNLOAD_WRITE 31
#define ROBOT_SERVO_LOAD_OR_UNLOAD_READ  32
#define ROBOT_SERVO_LED_CTRL_WRITE       33
#define ROBOT_SERVO_LED_CTRL_READ        34
#define ROBOT_SERVO_LED_ERROR_WRITE      35
#define ROBOT_SERVO_LED_ERROR_READ       36

/* 舵机中点位置 */
#define ROBOT_SERVO_MIDDLE      500
/* 舵机指令缓冲区大小 */
#define CMD_Size            20
/* 每行前8个值按顺序对应舵机ID，第9个为舵机运行时间 */
#define Array_size          9

//宏函数 获得A的低八位
#define GET_LOW_BYTE(A) (uint8_t)((A))
//宏函数 获得A的高八位
#define GET_HIGH_BYTE(A) (uint8_t)((A) >> 8)
//宏函数 以A为高八位 B为低八位 合并为16位整形
#define BYTE_TO_HW(A, B) ((((uint16_t)(A)) << 8) | (uint8_t)(B))



class RobotServoFw
{
protected:
    uint8_t RobotCheckSum(uint8_t (&buf)[CMD_Size]);

public:
    RobotServoFw();
    RobotServoFw(HardwareSerial &Handle);
#if !(defined(ESP8266) || defined(ESP32))
    RobotServoFw(SoftwareSerial &Handle);
#endif
    ~RobotServoFw();

    void RobotSerialServoMove(uint8_t id, int16_t position, uint16_t time);

    HardwareSerial *HardSerialX;
#if !(defined(ESP8266) || defined(ESP32))
    SoftwareSerial *SoftSerialX;
#endif
};

#endif  /* __ROBOTSERVOFW_H__ */
